From 780304f1404be14ef1d0f551002d35d84464248e Mon Sep 17 00:00:00 2001 From: Jeremy Bicha Date: Wed, 22 Nov 2017 09:53:25 -0500 Subject: [PATCH] New upstream version 0.1.38 --- INSTALL | 10 +- NEWS | 12 +- README | 22 +++- babl/babl-cache.c | 28 +++-- babl/babl-conversion.c | 6 +- babl/babl-format.c | 29 +++-- babl/babl-icc.c | 2 +- babl/babl-internal.c | 2 +- babl/babl-memory.c | 2 +- babl/babl-palette.c | 2 +- babl/babl-space.c | 9 +- babl/babl-trc.c | 10 +- babl/babl-util.c | 12 +- babl/babl-version.h | 2 +- babl/babl.h | 9 ++ babl/base/pow-24.c | 30 ++++- babl/base/pow-24.h | 30 ++++- configure | 30 ++--- configure.ac | 2 +- export-symbols | 1 + extensions/CIE.c | 258 +++++++++++++++++++++++++++++++++++++--- extensions/gggl-lies.c | 5 +- extensions/gggl.c | 13 +- extensions/sse2-float.c | 30 +++++ 24 files changed, 467 insertions(+), 89 deletions(-) diff --git a/INSTALL b/INSTALL index ea3004f..d2dc506 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,5 @@ -babl 0.1.34 +babl 0.1.38 Dynamic; any to any, pixel format conversion library. @@ -12,10 +12,10 @@ From a released version the following is the expected method of installation (or a variation on this theme): ------------------------------------------------------------ - foo$ wget ftp://ftp.gtk.org/pub/babl/0.1/babl-0.1.34.tar.bz2 - foo$ tar jxf babl-0.1.34.tar.gz - foo$ cd babl-0.1.34 - foo/babl-0.1.34$ ./configure && make && sudo make install + foo$ wget ftp://ftp.gtk.org/pub/babl/0.1/babl-0.1.38.tar.bz2 + foo$ tar jxf babl-0.1.38.tar.gz + foo$ cd babl-0.1.38 + foo/babl-0.1.38$ ./configure && make && sudo make install ------------------------------------------------------------ diff --git a/NEWS b/NEWS index c50a4ef..fba23b6 100644 --- a/NEWS +++ b/NEWS @@ -1,9 +1,17 @@
+ +2017-11-15 babl-0.1.38
+Added format "CIE L float", a couple of protections against division by 0.0 +
+2017-11-10 babl-0.1.36
+Optimized customized primary aware code paths for CIE Lab<->RGB conversions, +improved accuracy of gamma approximations. New API babl_format_exists() for +checking validity of babl format name, crash proofing of cache handling and use +of environment variables. +
2017-10-06 babl-0.1.34
Brown paper bag release, Fix indexed / custom primaries conflict, and re-export a symbol used by old GEGL/GIMPs. diff --git a/README b/README index 6472d36..d213b53 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Babl-0.1.34 +Babl-0.1.38 Contents @@ -64,6 +64,14 @@ babl release. If there are significant improvements to babl when a GEGL release is done a babl release is most often put out just prior to the GEGL release. +2017-11-15 babl-0.1.38 + Added format "CIE L float", a couple of protections against + division by 0.0 +2017-11-10 babl-0.1.36 + Optimized customized primary aware code paths for CIE Lab<->RGB + conversions, improved accuracy of gamma approximations. New API + babl_format_exists() for checking validity of babl format name, + crash proofing of cache handling and use of environment variables. 2017-10-06 babl-0.1.34 Brown paper bag release, Fix indexed / custom primaries conflict, and re-export a symbol used by old GEGL/GIMPs. @@ -1691,6 +1699,16 @@ components float CIE b float A +CIE L float + +bytes/pixel + 4 +model + CIE Lab +components + + float CIE L + CIE L alpha float bytes/pixel @@ -2186,4 +2204,4 @@ Massimo Valentini Ell fast paths -/babl-0.1.34 +/babl-0.1.38 diff --git a/babl/babl-cache.c b/babl/babl-cache.c index fa3f387..dcc76f4 100644 --- a/babl/babl-cache.c +++ b/babl/babl-cache.c @@ -37,6 +37,7 @@ mk_ancestry_iter (const char *path) { char copy[4096]; strncpy (copy, path, 4096); + copy[sizeof (copy) - 1] = '\0'; if (strrchr (copy, '/')) { *strrchr (copy, '/') = '\0'; @@ -63,6 +64,7 @@ mk_ancestry (const char *path) { char copy[4096]; strncpy (copy, path, 4096); + copy[sizeof (copy) - 1] = '\0'; #ifdef _WIN32 for (char *c = copy; *c; c++) if (*c == '\\') @@ -77,18 +79,19 @@ static const char *fish_cache_path (void) static char path[4096]; strncpy (path, FALLBACK_CACHE_PATH, 4096); + path[sizeof (path) - 1] = '\0'; #ifndef _WIN32 if (getenv ("XDG_CACHE_HOME")) - sprintf (path, "%s/babl/babl-fishes", getenv("XDG_CACHE_HOME")); + snprintf (path, sizeof (path), "%s/babl/babl-fishes", getenv("XDG_CACHE_HOME")); else if (getenv ("HOME")) - sprintf (path, "%s/.cache/babl/babl-fishes", getenv("HOME")); + snprintf (path, sizeof (path), "%s/.cache/babl/babl-fishes", getenv("HOME")); #else { char win32path[4096]; if (SHGetFolderPathA (NULL, CSIDL_LOCAL_APPDATA, NULL, SHGFP_TYPE_CURRENT, win32path) == S_OK) - sprintf (path, "%s\\%s\\babl-fishes.txt", win32path, BABL_LIBRARY); + snprintf (path, sizeof (path), "%s\\%s\\babl-fishes.txt", win32path, BABL_LIBRARY); else if (getenv ("TEMP")) - sprintf (path, "%s\\babl-fishes.txt", getenv("TEMP")); + snprintf (path, sizeof (path), "%s\\babl-fishes.txt", getenv("TEMP")); } #endif @@ -150,13 +153,13 @@ static const char *cache_header (void) { static char buf[2048]; if (strchr (BABL_GIT_VERSION, ' ')) // we must be building from tarball - sprintf (buf, "#%i.%i.%i BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f", + snprintf (buf, sizeof (buf), + "#%i.%i.%i BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f", BABL_MAJOR_VERSION, BABL_MINOR_VERSION, BABL_MICRO_VERSION, _babl_max_path_len (), _babl_legal_error ()); else - sprintf (buf, "#%s BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f", - BABL_GIT_VERSION, - _babl_max_path_len (), _babl_legal_error ()); + snprintf (buf, sizeof (buf), "#%s BABL_PATH_LENGTH=%d BABL_TOLERANCE=%f", + BABL_GIT_VERSION, _babl_max_path_len (), _babl_legal_error ()); return buf; } @@ -167,10 +170,15 @@ void babl_store_db (void) char *tmpp = calloc(8000,1); FILE *dbfile; - sprintf (tmpp, "%s~", fish_cache_path ()); + if (!tmpp) + return; + snprintf (tmpp, 8000, "%s~", fish_cache_path ()); dbfile = fopen (tmpp, "w"); if (!dbfile) + { + free (tmpp); return; + } fprintf (dbfile, "%s\n", cache_header ()); /* sort the list of fishes by usage, making next run more efficient - @@ -270,6 +278,7 @@ void babl_init_db (void) { fprintf (stderr, "%s:%i: loading of cache failed\n", __FUNCTION__, __LINE__); + free (contents); return; } @@ -312,6 +321,7 @@ void babl_init_db (void) Babl *conv = (void*)babl_db_find(babl_conversion_db(), &token[1]); if (!conv) { + free (contents); return; } else diff --git a/babl/babl-conversion.c b/babl/babl-conversion.c index 75e5c93..17dccf8 100644 --- a/babl/babl-conversion.c +++ b/babl/babl-conversion.c @@ -154,7 +154,7 @@ create_name (Babl *source, Babl *destination, int type) { if (babl_extender ()) { - snprintf (buf, 512 - 1, "%s %i: %s%s to %s", + snprintf (buf, sizeof (buf), "%s %i: %s%s to %s", BABL (babl_extender ())->instance.name, collisions, type == BABL_CONVERSION_LINEAR ? "" : @@ -162,18 +162,16 @@ create_name (Babl *source, Babl *destination, int type) type == BABL_CONVERSION_PLANAR ? "planar " : "Eeeek! ", source->instance.name, destination->instance.name); - buf[511] = '\0'; } else { - snprintf (buf, 512 - 1, "%s %s to %s %i", + snprintf (buf, sizeof (buf), "%s %s to %s %i", type == BABL_CONVERSION_LINEAR ? "" : type == BABL_CONVERSION_PLANE ? "plane " : type == BABL_CONVERSION_PLANAR ? "planar " : "Eeeek! ", source->instance.name, destination->instance.name, collisions); - buf[511] = '\0'; } return buf; } diff --git a/babl/babl-format.c b/babl/babl-format.c index 4ed14d0..45c62b2 100644 --- a/babl/babl-format.c +++ b/babl/babl-format.c @@ -135,8 +135,8 @@ format_new_from_format_with_space (const Babl *format, const Babl *space) { Babl *ret; char new_name[256]; - sprintf (new_name, "%s-%s", babl_get_name ((void*)format), - babl_get_name ((void*)space)); + snprintf (new_name, sizeof (new_name), "%s-%s", babl_get_name ((void*)format), + babl_get_name ((void*)space)); ret = babl_db_find (babl_format_db(), new_name); if (ret) return ret; @@ -161,6 +161,7 @@ create_name (const BablModel *model, { char buf[512] = ""; char *p = &buf[0]; + ssize_t left; int i; int same_types = 1; const BablType**t = type; @@ -168,9 +169,11 @@ create_name (const BablModel *model, BablComponent **c1 = component; BablComponent **c2 = model->component; - - sprintf (p, "%s ", model->instance.name); + left = 512; + snprintf (p, left, "%s ", model->instance.name); p += strlen (model->instance.name) + 1; + left -= strlen (model->instance.name) + 1; + babl_assert (left >= 0); i = components; while (i--) @@ -202,7 +205,7 @@ create_name (const BablModel *model, if (same_types) { - sprintf (p, "%s", first_type->instance.name); + snprintf (p, left, "%s", first_type->instance.name); return babl_strdup (buf); } @@ -210,11 +213,14 @@ create_name (const BablModel *model, while (i--) { - sprintf (p, "(%s as %s) ", + snprintf (p, left, "(%s as %s) ", (*component)->instance.name, (*type)->instance.name); p += strlen ((*component)->instance.name) + strlen ((*type)->instance.name) + strlen ("( as ) "); + left -= strlen ((*component)->instance.name) + + strlen ((*type)->instance.name) + strlen ("( as ) "); + babl_assert (left >= 0); component++; type++; } @@ -226,7 +232,7 @@ ncomponents_create_name (const Babl *type, int components) { char buf[512]; - sprintf (buf, "%s[%i] ", type->instance.name, components); + snprintf (buf, sizeof (buf), "%s[%i] ", type->instance.name, components); return babl_strdup (buf); } @@ -742,4 +748,13 @@ babl_format_with_space (const char *name, const Babl *space) return ret; } +int +babl_format_exists (const char *name) +{ + if (babl_db_exist_by_name (db, name)) + return 1; + return 0; +} + + diff --git a/babl/babl-icc.c b/babl/babl-icc.c index 45ba8fa..20841b9 100644 --- a/babl/babl-icc.c +++ b/babl/babl-icc.c @@ -973,7 +973,7 @@ char *babl_icc_get_key (const char *icc_data, { char tag[5]; int val = icc_read (u32, 64); - sprintf (tag, "%i", val); + snprintf (tag, sizeof (tag), "%i", val); return strdup (tag); } else if (!strcmp (key, "tags")) { diff --git a/babl/babl-internal.c b/babl/babl-internal.c index 0589e3f..e0b4f7a 100644 --- a/babl/babl-internal.c +++ b/babl/babl-internal.c @@ -65,7 +65,7 @@ babl_backtrack (void) { char buf[512]; - sprintf (buf, "echo bt>/tmp/babl.gdb;" + snprintf (buf, sizeof (buf), "echo bt>/tmp/babl.gdb;" "gdb -q --batch -x /tmp/babl.gdb --pid=%i | grep 'in ''babl_die' -A40", getpid ()); return system (buf); } diff --git a/babl/babl-memory.c b/babl/babl-memory.c index d9e4d2f..d0229e4 100644 --- a/babl/babl-memory.c +++ b/babl/babl-memory.c @@ -71,7 +71,7 @@ mem_stats (void) { static char buf[128]; - sprintf (buf, "mallocs:%i callocs:%i strdups:%i dups:%i allocs:%i frees:%i reallocs:%i\t|", + snprintf (buf, sizeof (buf), "mallocs:%i callocs:%i strdups:%i dups:%i allocs:%i frees:%i reallocs:%i\t|", mallocs, callocs, strdups, dups, mallocs + callocs + strdups + dups, frees, reallocs); return buf; } diff --git a/babl/babl-palette.c b/babl/babl-palette.c index 823ff0c..fda96ae 100644 --- a/babl/babl-palette.c +++ b/babl/babl-palette.c @@ -483,7 +483,7 @@ const Babl *babl_new_palette (const char *name, if (!name) { static int cnt = 0; - sprintf (cname, "_babl-int-%i", cnt++); + snprintf (cname, sizeof (cname), "_babl-int-%i", cnt++); name = cname; } else diff --git a/babl/babl-space.c b/babl/babl-space.c index adc9e7a..781e419 100644 --- a/babl/babl-space.c +++ b/babl/babl-space.c @@ -285,9 +285,9 @@ babl_space_from_rgbxyz_matrix (const char *name, space_db[i]=space; space_db[i].instance.name = space_db[i].name; if (name) - sprintf (space_db[i].name, "%s", name); + snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name); else - sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s", + snprintf (space_db[i].name, sizeof (space_db[i].name), "space-%.4f,%.4f_%.4f,%.4f_%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s", rx, gx, bx, ry, gy, by, rz, gz, bz, @@ -348,10 +348,11 @@ babl_space_from_chromaticities (const char *name, space_db[i]=space; space_db[i].instance.name = space_db[i].name; if (name) - sprintf (space_db[i].name, "%s", name); + snprintf (space_db[i].name, sizeof (space_db[i].name), "%s", name); else /* XXX: this can get longer than 256bytes ! */ - sprintf (space_db[i].name, "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s", + snprintf (space_db[i].name, sizeof (space_db[i].name), + "space-%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%.4f,%.4f_%s,%s,%s", wx,wy,rx,ry,bx,by,gx,gy,babl_get_name (space.trc[0]), babl_get_name(space.trc[1]), babl_get_name(space.trc[2])); diff --git a/babl/babl-trc.c b/babl/babl-trc.c index 7524ef8..0a00710 100644 --- a/babl/babl-trc.c +++ b/babl/babl-trc.c @@ -292,11 +292,11 @@ babl_trc_new (const char *name, trc_db[i]=trc; trc_db[i].instance.name = trc_db[i].name; if (name) - sprintf (trc_db[i].name, "%s", name); + snprintf (trc_db[i].name, sizeof (trc_db[i].name), "%s", name); else if (n_lut) - sprintf (trc_db[i].name, "lut-trc"); + snprintf (trc_db[i].name, sizeof (trc_db[i].name), "lut-trc"); else - sprintf (trc_db[i].name, "trc-%i-%f", type, gamma); + snprintf (trc_db[i].name, sizeof (trc_db[i].name), "trc-%i-%f", type, gamma); if (n_lut) { @@ -430,7 +430,7 @@ babl_trc_formula_srgb (double g, double a, double b, double c, double d) fabs (c - (-3417)) < 0.01) return babl_trc ("sRGB"); - sprintf (name, "%.6f %.6f %.4f %.4f %.4f", g, a, b, c, d); + snprintf (name, sizeof (name), "%.6f %.6f %.4f %.4f %.4f", g, a, b, c, d); for (i = 0; name[i]; i++) if (name[i] == ',') name[i] = '.'; while (name[strlen(name)-1]=='0') @@ -446,7 +446,7 @@ babl_trc_gamma (double gamma) if (fabs (gamma - 1.0) < 0.01) return babl_trc_new ("linear", BABL_TRC_LINEAR, 1.0, 0, NULL); - sprintf (name, "%.6f", gamma); + snprintf (name, sizeof (name), "%.6f", gamma); for (i = 0; name[i]; i++) if (name[i] == ',') name[i] = '.'; while (name[strlen(name)-1]=='0') diff --git a/babl/babl-util.c b/babl/babl-util.c index 23c1513..60b695d 100644 --- a/babl/babl-util.c +++ b/babl/babl-util.c @@ -116,10 +116,18 @@ _babl_file_get_contents (const char *path, if (!file) return -1; - fseek (file, 0, SEEK_END); - size = ftell (file); + if (fseek (file, 0, SEEK_END) == -1 || (size = ftell (file)) == -1) + { + fclose (file); + return -1; + } if (length) *length = size; rewind (file); + if ((size_t) size > SIZE_MAX - 8) + { + fclose (file); + return -1; + } buffer = calloc(size + 8, 1); if (!buffer) diff --git a/babl/babl-version.h b/babl/babl-version.h index 4d1e2da..ed4a665 100644 --- a/babl/babl-version.h +++ b/babl/babl-version.h @@ -34,7 +34,7 @@ #define BABL_MAJOR_VERSION 0 #define BABL_MINOR_VERSION 1 -#define BABL_MICRO_VERSION 34 +#define BABL_MICRO_VERSION 38 /** Get the version information on the babl library */ void babl_get_version (int *major, diff --git a/babl/babl.h b/babl/babl.h index 5e299a7..a45de42 100644 --- a/babl/babl.h +++ b/babl/babl.h @@ -156,6 +156,15 @@ char *babl_icc_get_key (const char *icc_data, */ const Babl * babl_format (const char *name); +/** + * babl_format_exists: + * + * Returns 1 if the provided format name is known by babl or 0 if it is + * not. Can also be used to verify that specific extension formats are + * available (though this can also be inferred from the version of babl). + */ +int babl_format_exists (const char *name); + /** * babl_format_with_space: * diff --git a/babl/base/pow-24.c b/babl/base/pow-24.c index dbc4071..4587bf1 100644 --- a/babl/base/pow-24.c +++ b/babl/base/pow-24.c @@ -48,8 +48,13 @@ init_newton (double x, double exponent, double c0, double c1, double c2) double babl_pow_24 (double x) { - double y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332); + double y; int i; + if (x > 16.0) { + /* for large values, fall back to a slower but more accurate version */ + return exp (log (x) * 2.4); + } + y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332); for (i = 0; i < 3; i++) y = (1.+1./5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y)); x *= y; @@ -61,9 +66,14 @@ babl_pow_24 (double x) double babl_pow_1_24 (double x) { - double y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383); + double y; int i; double z; + if (x > 1024.0) { + /* for large values, fall back to a slower but more accurate version */ + return exp (log (x) * (1.0 / 2.4)); + } + y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383); x = sqrt (x); /* newton's method for x^(-1/6) */ z = (1./6.) * x; @@ -102,10 +112,15 @@ init_newtonf (float x, float exponent, float c0, float c1, float c2) float babl_pow_24f (float x) { - float y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f); + float y; int i; + if (x > 16.0f) { + /* for large values, fall back to a slower but more accurate version */ + return expf (logf (x) * 2.4f); + } + y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f); for (i = 0; i < 3; i++) - y = (1.f+1.f/5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y)); + y = (1.f+1.f/5)*y - ((1.f/5)*x*(y*y))*((y*y)*(y*y)); x *= y; return x*x*x; } @@ -115,9 +130,14 @@ babl_pow_24f (float x) float babl_pow_1_24f (float x) { - float y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f); + float y; int i; float z; + if (x > 1024.0f) { + /* for large values, fall back to a slower but more accurate version */ + return expf (logf (x) * (1.0f / 2.4f)); + } + y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f); x = sqrtf (x); /* newton's method for x^(-1/6) */ z = (1.f/6.f) * x; diff --git a/babl/base/pow-24.h b/babl/base/pow-24.h index a55c029..3ea6984 100644 --- a/babl/base/pow-24.h +++ b/babl/base/pow-24.h @@ -54,8 +54,13 @@ init_newton (double x, double exponent, double c0, double c1, double c2) static inline double babl_pow_24 (double x) { - double y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332); + double y; int i; + if (x > 16.0) { + /* for large values, fall back to a slower but more accurate version */ + return exp (log (x) * 2.4); + } + y = init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332); for (i = 0; i < 3; i++) y = (1.+1./5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y)); x *= y; @@ -67,9 +72,14 @@ babl_pow_24 (double x) static inline double babl_pow_1_24 (double x) { - double y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383); + double y; int i; double z; + if (x > 1024.0) { + /* for large values, fall back to a slower but more accurate version */ + return exp (log (x) * (1.0 / 2.4)); + } + y = init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383); x = sqrt (x); /* newton's method for x^(-1/6) */ z = (1./6.) * x; @@ -133,10 +143,15 @@ init_newtonf (float x, float exponent, float c0, float c1, float c2) static inline float babl_pow_24f (float x) { - float y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f); + float y; int i; + if (x > 16.0f) { + /* for large values, fall back to a slower but more accurate version */ + return expf (logf (x) * 2.4f); + } + y = init_newtonf (x, -1.f/5, 0.9953189663f, 0.9594345146f, 0.6742970332f); for (i = 0; i < 3; i++) - y = (1.f+1.f/5)*y - ((1./5)*x*(y*y))*((y*y)*(y*y)); + y = (1.f+1.f/5)*y - ((1.f/5)*x*(y*y))*((y*y)*(y*y)); x *= y; return x*x*x; } @@ -146,9 +161,14 @@ babl_pow_24f (float x) static inline float babl_pow_1_24f (float x) { - float y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f); + float y; int i; float z; + if (x > 1024.0f) { + /* for large values, fall back to a slower but more accurate version */ + return expf (logf (x) * (1.0f / 2.4f)); + } + y = init_newtonf (x, -1.f/12, 0.9976800269f, 0.9885126933f, 0.5908575383f); x = sqrtf (x); /* newton's method for x^(-1/6) */ z = (1.f/6.f) * x; diff --git a/configure b/configure index c808fee..bd885c5 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for babl 0.1.34. +# Generated by GNU Autoconf 2.69 for babl 0.1.38. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -587,8 +587,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='babl' PACKAGE_TARNAME='babl' -PACKAGE_VERSION='0.1.34' -PACKAGE_STRING='babl 0.1.34' +PACKAGE_VERSION='0.1.38' +PACKAGE_STRING='babl 0.1.38' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1381,7 +1381,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures babl 0.1.34 to adapt to many kinds of systems. +\`configure' configures babl 0.1.38 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1453,7 +1453,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of babl 0.1.34:";; + short | recursive ) echo "Configuration of babl 0.1.38:";; esac cat <<\_ACEOF @@ -1573,7 +1573,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -babl configure 0.1.34 +babl configure 0.1.38 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1938,7 +1938,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by babl $as_me 0.1.34, which was +It was created by babl $as_me 0.1.38, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2294,11 +2294,11 @@ ac_config_headers="$ac_config_headers config.h" BABL_MAJOR_VERSION=0 BABL_MINOR_VERSION=1 -BABL_MICRO_VERSION=34 +BABL_MICRO_VERSION=38 BABL_INTERFACE_AGE=1 -BABL_BINARY_AGE=134 -BABL_VERSION=0.1.34 -BABL_REAL_VERSION=0.1.34 +BABL_BINARY_AGE=138 +BABL_VERSION=0.1.38 +BABL_REAL_VERSION=0.1.38 BABL_API_VERSION=0.1 @@ -2333,7 +2333,7 @@ fi -BABL_LIBRARY_VERSION="133:1:133" +BABL_LIBRARY_VERSION="137:1:137" BABL_CURRENT_MINUS_AGE=0 @@ -2965,7 +2965,7 @@ fi # Define the identity of the package. PACKAGE='babl' - VERSION='0.1.34' + VERSION='0.1.38' # Some tools Automake needs. @@ -14864,7 +14864,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by babl $as_me 0.1.34, which was +This file was extended by babl $as_me 0.1.38, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14930,7 +14930,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -babl config.status 0.1.34 +babl config.status 0.1.38 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index dda45b1..c1fd10f 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ AC_PREREQ(2.54) m4_define([babl_major_version], [0]) m4_define([babl_minor_version], [1]) -m4_define([babl_micro_version], [34]) +m4_define([babl_micro_version], [38]) m4_define([babl_real_version], [babl_major_version.babl_minor_version.babl_micro_version]) m4_define([babl_version], [babl_real_version]) diff --git a/export-symbols b/export-symbols index 2ba4bb8..f85fec9 100644 --- a/export-symbols +++ b/export-symbols @@ -8,6 +8,7 @@ babl_exit babl_fast_fish babl_fish babl_format +babl_format_exists babl_format_get_bytes_per_pixel babl_format_get_model babl_format_get_n_components diff --git a/extensions/CIE.c b/extensions/CIE.c index d16d862..658fd2a 100644 --- a/extensions/CIE.c +++ b/extensions/CIE.c @@ -2,6 +2,7 @@ * Copyright (C) 2005, 2014 Øyvind Kolås. * Copyright (C) 2009, Martin Nordholts * Copyright (C) 2014, Elle Stone + * Copyright (C) 2017, Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -168,13 +169,13 @@ XYZ_to_LAB (double X, double y_r = Y / D50_WHITE_REF_Y; double z_r = Z / D50_WHITE_REF_Z; - if (x_r > LAB_EPSILON) f_x = pow(x_r, 1.0 / 3.0); + if (x_r > LAB_EPSILON) f_x = cbrt(x_r); else ( f_x = ((LAB_KAPPA * x_r) + 16) / 116.0 ); - if (y_r > LAB_EPSILON) f_y = pow(y_r, 1.0 / 3.0); + if (y_r > LAB_EPSILON) f_y = cbrt(y_r); else ( f_y = ((LAB_KAPPA * y_r) + 16) / 116.0 ); - if (z_r > LAB_EPSILON) f_z = pow(z_r, 1.0 / 3.0); + if (z_r > LAB_EPSILON) f_z = cbrt(z_r); else ( f_z = ((LAB_KAPPA * z_r) + 16) / 116.0 ); *to_L = (116.0 * f_y) - 16.0; @@ -591,6 +592,44 @@ cubef (float f) return f * f * f; } +static void +Yf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + float yr = src[0]; + float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr; + + dst[0] = L; + + src++; + dst++; + } +} + +static void +Yaf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + float yr = src[0]; + float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr; + + dst[0] = L; + + src += 2; + dst += 1; + } +} + static void Yaf_to_Laf (const Babl *conversion,float *src, float *dst, @@ -617,6 +656,16 @@ rgbf_to_Labf (const Babl *conversion,float *src, float *dst, long samples) { + const Babl *space = babl_conversion_get_source_space (conversion); + float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X; + float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X; + float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X; + float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y; + float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y; + float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y; + float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z; + float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z; + float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z; long n = samples; while (n--) @@ -625,9 +674,9 @@ rgbf_to_Labf (const Babl *conversion,float *src, float g = src[1]; float b = src[2]; - float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b; - float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b; - float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b; + float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b; + float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b; + float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b; float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f; float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f; @@ -646,11 +695,95 @@ rgbf_to_Labf (const Babl *conversion,float *src, } } +static void +rgbaf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y; + float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y; + float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y; + long n = samples; + + while (n--) + { + float r = src[0]; + float g = src[1]; + float b = src[2]; + + float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b; + + float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f; + + float L = 116.0f * fy - 16.0f; + + dst[0] = L; + + src += 4; + dst += 1; + } +} + +static void +rgbaf_to_Labf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X; + float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X; + float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X; + float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y; + float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y; + float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y; + float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z; + float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z; + float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z; + long n = samples; + + while (n--) + { + float r = src[0]; + float g = src[1]; + float b = src[2]; + + float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b; + float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b; + float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b; + + float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f; + float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f; + float fz = zr > LAB_EPSILON ? _cbrtf (zr) : (LAB_KAPPA * zr + 16.0f) / 116.0f; + + float L = 116.0f * fy - 16.0f; + float A = 500.0f * (fx - fy); + float B = 200.0f * (fy - fz); + + dst[0] = L; + dst[1] = A; + dst[2] = B; + + src += 4; + dst += 3; + } +} + static void rgbaf_to_Labaf (const Babl *conversion,float *src, float *dst, long samples) { + const Babl *space = babl_conversion_get_source_space (conversion); + float m_0_0 = space->space.RGBtoXYZf[0] / D50_WHITE_REF_X; + float m_0_1 = space->space.RGBtoXYZf[1] / D50_WHITE_REF_X; + float m_0_2 = space->space.RGBtoXYZf[2] / D50_WHITE_REF_X; + float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y; + float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y; + float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y; + float m_2_0 = space->space.RGBtoXYZf[6] / D50_WHITE_REF_Z; + float m_2_1 = space->space.RGBtoXYZf[7] / D50_WHITE_REF_Z; + float m_2_2 = space->space.RGBtoXYZf[8] / D50_WHITE_REF_Z; long n = samples; while (n--) @@ -660,9 +793,9 @@ rgbaf_to_Labaf (const Babl *conversion,float *src, float b = src[2]; float a = src[3]; - float xr = 0.43603516f / D50_WHITE_REF_X * r + 0.38511658f / D50_WHITE_REF_X * g + 0.14305115f / D50_WHITE_REF_X * b; - float yr = 0.22248840f / D50_WHITE_REF_Y * r + 0.71690369f / D50_WHITE_REF_Y * g + 0.06060791f / D50_WHITE_REF_Y * b; - float zr = 0.01391602f / D50_WHITE_REF_Z * r + 0.09706116f / D50_WHITE_REF_Z * g + 0.71392822f / D50_WHITE_REF_Z * b; + float xr = m_0_0 * r + m_0_1 * g + m_0_2 * b; + float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b; + float zr = m_2_0 * r + m_2_1 * g + m_2_2 * b; float fx = xr > LAB_EPSILON ? _cbrtf (xr) : (LAB_KAPPA * xr + 16.0f) / 116.0f; float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f; @@ -682,11 +815,53 @@ rgbaf_to_Labaf (const Babl *conversion,float *src, } } +static void +Labf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + dst[0] = src[0]; + + src += 3; + dst += 1; + } +} + +static void +Labaf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + dst[0] = src[0]; + + src += 4; + dst += 1; + } +} + static void Labf_to_rgbf (const Babl *conversion,float *src, float *dst, long samples) { + const Babl *space = babl_conversion_get_source_space (conversion); + float m_0_0 = space->space.XYZtoRGBf[0] * D50_WHITE_REF_X; + float m_0_1 = space->space.XYZtoRGBf[1] * D50_WHITE_REF_Y; + float m_0_2 = space->space.XYZtoRGBf[2] * D50_WHITE_REF_Z; + float m_1_0 = space->space.XYZtoRGBf[3] * D50_WHITE_REF_X; + float m_1_1 = space->space.XYZtoRGBf[4] * D50_WHITE_REF_Y; + float m_1_2 = space->space.XYZtoRGBf[5] * D50_WHITE_REF_Z; + float m_2_0 = space->space.XYZtoRGBf[6] * D50_WHITE_REF_X; + float m_2_1 = space->space.XYZtoRGBf[7] * D50_WHITE_REF_Y; + float m_2_2 = space->space.XYZtoRGBf[8] * D50_WHITE_REF_Z; long n = samples; while (n--) @@ -703,9 +878,9 @@ Labf_to_rgbf (const Babl *conversion,float *src, float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA; float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA; - float r = 3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr -0.490724283042f * D50_WHITE_REF_Z * zr; - float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr +0.033453331711f * D50_WHITE_REF_Z * zr; - float b = 0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr +1.405718224383f * D50_WHITE_REF_Z * zr; + float r = m_0_0 * xr + m_0_1 * yr + m_0_2 * zr; + float g = m_1_0 * xr + m_1_1 * yr + m_1_2 * zr; + float b = m_2_0 * xr + m_2_1 * yr + m_2_2 * zr; dst[0] = r; dst[1] = g; @@ -721,6 +896,16 @@ Labaf_to_rgbaf (const Babl *conversion,float *src, float *dst, long samples) { + const Babl *space = babl_conversion_get_source_space (conversion); + float m_0_0 = space->space.XYZtoRGBf[0] * D50_WHITE_REF_X; + float m_0_1 = space->space.XYZtoRGBf[1] * D50_WHITE_REF_Y; + float m_0_2 = space->space.XYZtoRGBf[2] * D50_WHITE_REF_Z; + float m_1_0 = space->space.XYZtoRGBf[3] * D50_WHITE_REF_X; + float m_1_1 = space->space.XYZtoRGBf[4] * D50_WHITE_REF_Y; + float m_1_2 = space->space.XYZtoRGBf[5] * D50_WHITE_REF_Z; + float m_2_0 = space->space.XYZtoRGBf[6] * D50_WHITE_REF_X; + float m_2_1 = space->space.XYZtoRGBf[7] * D50_WHITE_REF_Y; + float m_2_2 = space->space.XYZtoRGBf[8] * D50_WHITE_REF_Z; long n = samples; while (n--) @@ -738,9 +923,9 @@ Labaf_to_rgbaf (const Babl *conversion,float *src, float xr = cubef (fx) > LAB_EPSILON ? cubef (fx) : (fx * 116.0f - 16.0f) / LAB_KAPPA; float zr = cubef (fz) > LAB_EPSILON ? cubef (fz) : (fz * 116.0f - 16.0f) / LAB_KAPPA; - float r = 3.134274799724f * D50_WHITE_REF_X * xr -1.617275708956f * D50_WHITE_REF_Y * yr -0.490724283042f * D50_WHITE_REF_Z * zr; - float g = -0.978795575994f * D50_WHITE_REF_X * xr +1.916161689117f * D50_WHITE_REF_Y * yr +0.033453331711f * D50_WHITE_REF_Z * zr; - float b = 0.071976988401f * D50_WHITE_REF_X * xr -0.228984974402f * D50_WHITE_REF_Y * yr +1.405718224383f * D50_WHITE_REF_Z * zr; + float r = m_0_0 * xr + m_0_1 * yr + m_0_2 * zr; + float g = m_1_0 * xr + m_1_1 * yr + m_1_2 * zr; + float b = m_2_0 * xr + m_2_1 * yr + m_2_2 * zr; dst[0] = r; dst[1] = g; @@ -903,6 +1088,12 @@ conversions (void) "linear", Labf_to_rgbf, NULL ); + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("CIE Lab float"), + "linear", rgbaf_to_Labf, + NULL + ); babl_conversion_new ( babl_format ("RGBA float"), babl_format ("CIE Lab alpha float"), @@ -915,12 +1106,42 @@ conversions (void) "linear", Labaf_to_rgbaf, NULL ); + babl_conversion_new ( + babl_format ("Y float"), + babl_format ("CIE L float"), + "linear", Yf_to_Lf, + NULL + ); + babl_conversion_new ( + babl_format ("YA float"), + babl_format ("CIE L float"), + "linear", Yaf_to_Lf, + NULL + ); babl_conversion_new ( babl_format ("YA float"), babl_format ("CIE L alpha float"), "linear", Yaf_to_Laf, NULL ); + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("CIE L float"), + "linear", rgbaf_to_Lf, + NULL + ); + babl_conversion_new ( + babl_format ("CIE Lab float"), + babl_format ("CIE L float"), + "linear", Labf_to_Lf, + NULL + ); + babl_conversion_new ( + babl_format ("CIE Lab alpha float"), + babl_format ("CIE L float"), + "linear", Labaf_to_Lf, + NULL + ); babl_conversion_new ( babl_model ("RGBA"), babl_model ("CIE LCH(ab)"), @@ -1019,6 +1240,13 @@ formats (void) babl_component ("A"), NULL); + babl_format_new ( + "name", "CIE L float", + babl_model ("CIE Lab"), + babl_type ("float"), + babl_component ("CIE L"), + NULL); + babl_format_new ( "name", "CIE L alpha float", babl_model ("CIE Lab alpha"), diff --git a/extensions/gggl-lies.c b/extensions/gggl-lies.c index b34f8ef..c08dccd 100644 --- a/extensions/gggl-lies.c +++ b/extensions/gggl-lies.c @@ -356,7 +356,10 @@ conv_gAF_gaF (const Babl *conversion,unsigned char *src, unsigned char *dst, lon { float alpha = (*(float *) (src + 4)); - *(float *) dst = ((*(float *) src) / alpha); + if (alpha == 0.0f) + *(float *) dst = 0.0f; + else + *(float *) dst = ((*(float *) src) / alpha); dst += 4; src += 4; *(float *) dst = alpha; diff --git a/extensions/gggl.c b/extensions/gggl.c index 83352d2..cf83988 100644 --- a/extensions/gggl.c +++ b/extensions/gggl.c @@ -373,7 +373,10 @@ conv_gAF_gaF (const Babl *conversion,unsigned char *src, unsigned char *dst, lon { float alpha = (*(float *) (src + 4)); - *(float *) dst = ((*(float *) src) / alpha); + if (alpha == 0.0f) + *(float *) dst = 0.0f; + else + *(float *) dst = ((*(float *) src) / alpha); dst += 4; src += 4; *(float *) dst = alpha; @@ -557,10 +560,16 @@ conv_rgbA16_rgbaF (const Babl *conversion,unsigned char *src, unsigned char *dst { float alpha = (((unsigned short *) src)[3]) / 65535.0; int c; + float recip_alpha; + + if (alpha == 0.0f) + recip_alpha = 10000.0; + else + recip_alpha = 1.0/alpha; for (c = 0; c < 3; c++) { - (*(float *) dst) = (*(unsigned short *) src / 65535.0) / alpha; + (*(float *) dst) = (*(unsigned short *) src / 65535.0) * recip_alpha; dst += 4; src += 2; } diff --git a/extensions/sse2-float.c b/extensions/sse2-float.c index d26073c..223f85c 100644 --- a/extensions/sse2-float.c +++ b/extensions/sse2-float.c @@ -237,6 +237,22 @@ conv_rgbAF_linear_rgbaF_linear_spin (const Babl *conversion,const float *src, fl #define FLT_ONE 0x3f800000 // ((union {float f; int i;}){1.0f}).i #define FLT_MANTISSA (1<<23) +static inline float +sse_max_component (__v4sf x) { + __v4sf s; + __v4sf m; + + /* m = [max (x[3], x[1]), max (x[2], x[0])] */ + s = (__v4sf) _mm_shuffle_epi32 ((__m128i) x, _MM_SHUFFLE(0, 0, 3, 2)); + m = _mm_max_ps (x, s); + + /* m = [max (m[1], m[0])] = [max (max (x[3], x[1]), max (x[2], x[0]))] */ + s = (__v4sf) _mm_shuffle_epi32 ((__m128i) m, _MM_SHUFFLE(0, 0, 0, 1)); + m = _mm_max_ps (m, s); + + return m[0]; +} + static inline __v4sf sse_init_newton (__v4sf x, double exponent, double c0, double c1, double c2) { @@ -249,6 +265,13 @@ static inline __v4sf sse_pow_1_24 (__v4sf x) { __v4sf y, z; + if (sse_max_component (x) > 1024.0f) { + /* for large values, fall back to a slower but more accurate version */ + return _mm_set_ps (expf (logf (x[3]) * (1.0f / 2.4f)), + expf (logf (x[2]) * (1.0f / 2.4f)), + expf (logf (x[1]) * (1.0f / 2.4f)), + expf (logf (x[0]) * (1.0f / 2.4f))); + } y = sse_init_newton (x, -1./12, 0.9976800269, 0.9885126933, 0.5908575383); x = _mm_sqrt_ps (x); /* newton's method for x^(-1/6) */ @@ -262,6 +285,13 @@ static inline __v4sf sse_pow_24 (__v4sf x) { __v4sf y, z; + if (sse_max_component (x) > 16.0f) { + /* for large values, fall back to a slower but more accurate version */ + return _mm_set_ps (expf (logf (x[3]) * 2.4f), + expf (logf (x[2]) * 2.4f), + expf (logf (x[1]) * 2.4f), + expf (logf (x[0]) * 2.4f)); + } y = sse_init_newton (x, -1./5, 0.9953189663, 0.9594345146, 0.6742970332); /* newton's method for x^(-1/5) */ z = splat4f (1.f/5.f) * x; -- 2.30.2